#ifndef _JIAJIA_STREAM_H
#define _JIAJIA_STREAM_H

#include "yu.h"

#define _JIAJIA_STREAM_MIN_BUF_SIZE 4096

#define JIAJIA_STREAM_OPEN_SUCC 0
#define JIAJIA_STREAM_OPEN_FAIL 1
#define JIAJIA_STREAM_OPEN_NOEXIT 2
#define JIAJIA_STREAM_OPEN_NOTYPE 3

#define _JiaJia_stream_init_once(stream)        \
    do{                                         \
        (stream)->forward = 0;                  \
        (stream)->back = 0;                     \
        (stream)->rows = 1;                     \
        (stream)->cols = 1;                     \
        (stream)->buf_size = 0;                 \
        (stream)->buf = NULL;                   \
        Yu_text_init(&((stream)->text));        \
    }while(0)

#define JiaJia_stream_init(stream) JiaJia_stream_meminit((void *)stream, sizeof(JiaJia_stream_t))
#define JiaJia_stream_free(stream) JiaJia_stream_memfree((void *)stream, sizeof(JiaJia_stream_t))

#define _JiaJia_stream_bufinit(stream)                                  \
    do{                                                                 \
        (stream)->buf = Yu_alloc(sizeof(unicode_t) *                    \
                                 _JIAJIA_STREAM_MIN_BUF_SIZE, NULL, NULL); \
        (stream)->buf_size = _JiaJia_STREAM_MIN_BUF_SIZE;               \
        (stream)->buf[0] = YU_UNICODE_EOF;                              \
    }while(0)

#define JiaJia_stream_close(stream) JiaJia_file_free(stream)
#define JiaJia_stream_rows(stream) ((stream)->rows)
#define JiaJia_stream_cols(stream) ((stream)->cols)

typedef struct JiaJia_stream{
    uint32_t forward;           /* 前进位置 */
    uint32_t back;              /* 后追位置 */
    uint32_t rows;              /* 行 */
    uint32_t cols;              /* 列 */
    size_t buf_size;            /* 缓存的大小 */
    unicode_t *buf;             /* 字符缓存 */
    Yu_text_t text;             /* yu 文本加载 */
} JiaJia_stream_t, *JiaJia_stream_pt;

extern void JiaJia_stream_meminit(void *, size_t);
extern void JiaJia_stream_memfree(void *, size_t);

extern int32_t JiaJia_stream_open(JiaJia_stream_pt, const char *);

extern unicode_t JiaJia_stream_next_unicode(JiaJia_stream_pt);
extern unicode_t JiaJia_stream_back_unicode(JiaJia_stream_pt);
extern unicode_t JiaJia_stream_throw_unicode(JiaJia_stream_pt);
extern void JiaJia_stream_throw_string(JiaJia_stream_pt, Yu_string_pt);

#endif
